package com.ksyun.campus.metaserver.controller;

import com.ksyun.campus.metaserver.domain.DataServerInfo;
import com.ksyun.campus.metaserver.domain.FileInfo;
import com.ksyun.campus.metaserver.domain.Result;
import com.ksyun.campus.metaserver.mapper.FileInfoMapper;
import com.ksyun.campus.metaserver.service.FileService;
import com.ksyun.campus.metaserver.service.MetaService;
import com.ksyun.campus.metaserver.services.RegistService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;

@RestController("/")
public class MetaController {


    private final Logger logger = LoggerFactory.getLogger(MetaController.class);

    @Resource
    private RegistService registService;

    @Resource
    private FileService fileService;

    @Resource
    private MetaService metaService;

    //获取一个项目的元信息
    @RequestMapping("stats")
    public Result stats(@RequestHeader String fileSystemName, @RequestParam String path) {
        return fileService.getFileInfo(fileSystemName, path);
    }

    //创建一个空文件
    @RequestMapping("create")
    public Result createFile(@RequestHeader String fileSystemName, @RequestParam String path) {
        //接收来自客户端创建文件请求
        Result result = metaService.pickDataServer();
        if (result.getCode().equals("500")) {
            //DataServer数量小于三个
            logger.error("DataServer数量小于三个，无法创建文件");
            return Result.fail("DataServer数量小于三个，无法创建文件");
        }
        List<DataServerInfo> dsList = (List<DataServerInfo>) result.getData();
        logger.info("选择的DataServer：{}", dsList);
        //在 三个DataServer根文件目录file下根据fileSystemName创建新的文件目录，这个就是一个文件系统，再根据path在这个文件系统里面创建文件（就是一次性创建了三个文件）
        if (fileService.createFile(fileSystemName, path, dsList))
            //在数据库记录该文件信息（包括文件的ID，保存在哪三个DataServer下）
            //创建成功后返回（此时文件的路径是/file/dataServer+ip+port /fileSystemName/path）
            return Result.success("创建文件成功", dsList);
        return Result.fail("创建文件失败，文件可能已经存在");
    }

    //创建一个文件夹
    @RequestMapping("mkdir")
    public Result mkdir(@RequestHeader String fileSystemName, @RequestParam String path) {
        //接收来自客户端创建文件夹请求
        Result result = metaService.pickDataServer();
        if (result.getCode().equals("500")) {
            //DataServer数量小于三个
            logger.error("DataServer数量小于三个，无法创建文件夹");
            return Result.fail("DataServer数量小于三个，无法创建文件夹");
        }
        List<DataServerInfo> dsList = (List<DataServerInfo>) result.getData();
        logger.info("选择的DataServer：{}", dsList);
        //在 三个DataServer根文件目录file下根据fileSystemName创建新的文件目录，这个就是一个文件系统，再根据path在这个文件系统里面创建文件（就是一次性创建了三个文件）
        if (fileService.createFolder(fileSystemName, path, dsList))
            //在数据库记录该文件信息（包括文件的ID，保存在哪三个DataServer下）
            //创建成功后返回（此时文件的路径是/file/dataServer+ip+port /fileSystemName/path）
            return Result.success("创建文件夹成功", dsList);
        return Result.fail("创建文件失败，文件夹可能已经存在");
    }

    //获取一个文件夹下的所有子项目
    @RequestMapping("listdir")
    public Result listdir(@RequestHeader String fileSystemName, @RequestParam String path) {
        return fileService.getListdir(fileSystemName, path);
    }

    //删除一个项目，可递归文件夹
    @RequestMapping("delete")
    public Result delete(@RequestHeader String fileSystemName, @RequestParam String path) {
        return fileService.delete(fileSystemName, path);
    }


    /**
     * 保存文件写入成功后的元数据信息，包括文件path、size、三副本信息等
     *
     * @param fileSystemName
     * @param path
     * @param
     * @param
     * @return
     */
    //更新文件大小信息
    @RequestMapping("write")
    public Result commitWrite(@RequestHeader String fileSystemName, @RequestParam String path, FileInfo fileInfo) {
        return fileService.updateFileInfo(fileSystemName, path, fileInfo);
    }


    /**
     * 根据文件path查询三副本的位置，返回客户端具体ds、文件分块信息
     *
     * @param fileSystemName
     * @param path
     * @return
     */
    @RequestMapping("open")
    public Result open(@RequestHeader String fileSystemName, @RequestParam String path) {
        return fileService.openFile(fileSystemName, path);
    }


    /**
     * 关闭退出进程
     */
    @RequestMapping("shutdown")
    public void shutdownServer() {
        System.out.println("安全退出");
        registService.closeZKClient();
        System.exit(-1);
    }

}
